Research
Security News
Quasar RAT Disguised as an npm Package for Detecting Vulnerabilities in Ethereum Smart Contracts
Socket researchers uncover a malicious npm package posing as a tool for detecting vulnerabilities in Etherium smart contracts.
nanocomponent
Advanced tools
Create performant HTML elements.
~4kb
var politeElement = component({
placeholder: function () {
return html`
<p>lol not loaded yet</p>
`
},
render: function () {
return html`
<p>HOW'S IT GOING CHAP</p>
`
}
})
console.log(politeElement())
setTimeout(function () {
console.log(politeElement())
}, 1000)
var widgetElement = component({
onload: function (el) {
el.textContent = 'totally loaded now'
},
onunload: function (el) {
el.textContent = 'no more free lunch'
},
onupdate: function (el, verb) {
el.textContent = `totally ${verb}ing now`
},
render: function (verb) {
return html`
<p>lol not ${verb}ed yet</p>
`
}
})
console.log(widgetElement('load'))
var el = widgetElement('blep')
document.body.appendChild(el)
document.body.removeChild(el)
var viewportElement = component({
onenter: function (el) {
el.textContent = 'BEHOLD THE GOBLIN'
},
onexit: function (el) {
el.textContent = 'THE PONIES HAVE COME'
},
render: function () {
return html`
<h1>WHO COULD IT BE</h1>
`
}
})
console.log(viewportElement())
var resizeElement = component({
onresize: function (el) {
var parent = el.parentNode
console.log('element dimensions', el.getBoundingRectangle())
console.log('parent dimensions', parent.getBoundingRectangle())
},
render: function () {
return html`
<div>hello planet</div>
`
}
})
console.log(resizeElement())
Check out nanocomponent-adapters on how to use nanocomponent
in
your fav framework.
Create an object with different methods attached. Cached until new arguments are passed in or when it's removed from the DOM. Availble methods are:
render
call to
the next requestIdleCallback
tick. This is useful to spread CPU intensive
work over more time and not block the render loop. When executed on the
server placeholder
will always be rendered in favor of render
. This makes
it easier for client-side JS to pick up where the server left off
(rehydration).render()
call is
called after an initial render with different arguments. Argument equality is
shallowly checked using a ===
check on each argument. The first argument is
the currently rendered argument.window.IntersectionObserver
window.IntersectionObserver
Call the corresponding render
function an receive DOM elements. As long as an
element exists on the DOM, subsequent calls to render
will return an empty
element with a .isSameNode()
method on it which can be used as a caching hint
for HTML diffing trees.
I've been building web stuff for a while now, and have seen a fair share of frameworks become popular, take over developer mindshare and then disappear again a few years later. With each framework iteration the basic libraries tend to be rewritten from scratch: form validation, modals, infinite scolls, charts. The list is long.
I think it'd be cool if we could create generic JS components that work natively with any JS framework through slim bindings. This would encourage reusability between frameworks, which means it becomes easier to pick up different frameworks (no need to relearn the ecosystem) and bring new frameworks to maturity (less new code to implement).
WebComponents are a specification by the W3C that's been in the works for a while now. Certain parts have been put on hold by browser vendors until kinks are ironed out, and the some of the available parts are not widely adopted - or at least not the way they were meant to be used.
When people talk about WebComponents they usually refer to the Custom Elements
specification. This spec allows you to create new HTML tags and provides you
with a set of lifecycle events. The onload
/ onunload
/ render
/
onupdate
events are indeed quite similar to Nanocomponent. The biggest
difference however, is the way in which elements are registered. Custom
Elements are globally scoped in the browser and must have unique names.
Nanocomponent is a plain JS function and will not run into namespacing issues.
It's quite feasible to wrap a Nanocomponent instance to create a Webcomponent.
The other way around is harder. Nanocomponent also exposes more events.
Sure! React Fiber (or React Stack, I'm not sure what name they're ending up with) is using the same APIs under the hood as Nanocomponent, but approaches it from the other side of the spectrum.
Nanocomponent is intended to create individual components that can run in any framework and have tight control over their performance. React Fiber is a framework where the whole render tree is optimized on each loop. Nanocomponent operates on the component layer, React Fiber at the framework layer.
This doesn't mean that either one is "better" - every abstraction carries overhead, and different situations require different solutions. I think it's great performance is being tackled from multiple sides of the spectrum.
Nanocomponent returns DOM elements that work in any framework that knows how to render raw DOM nodes. This includes pretty much every popular framework and compile-to-js language. Because the lifecycle events are self-encapsulated and we don't expose globals this means Nanocomponent doesn't have any problems running inside any other framework. I think Nanocomponent is quite similar in browser framework land to how C / CPP packages operate
All abstractions in JS come with a cost. Luckily the cost of Nanomorph is fairly low (4kb, CPU and memory seem to be cool - haven't noticed any significant repaint costs or anything), but it should not be neglected. Measure and inform yourself.
Nanomorph relies on fairly new DOM APIs to do what it does. If you're running
v. old browsers this package won't help you - we're sorry. As long as
window.MutationObserver
is available we should be good; the others are
optimizations on top. These are the fancy APIs we're using:
window.MutationObserver
window.IntersectionObserver
window.requestAnimationFrame
window.requestIdleCallback
Third of all this package is optimized for an environment that supports
require()
. I believe in iterating on proven ideas, and given the stability of
require()
and the tooling & community around it I'm betting that it'll stick
around for a while.
Some frameworks (like React Fiber / React Stack) might have some cool optimizations that allow super fine grained control over each and every element in the tree - nanocomponent is similar but has its own rules to wait for resources, so it might turn into an interesting situation where everyone is super politely waiting for resources and like is nice to each other. I don't know, but I'm guessing it'll be fun hah.
Also these components won't work in environments that don't have a DOM, but I bet it'd be cool to look at those environments and figure out which primitives they have and create equivalent functionality through generic components.
Yes!
Yup, it does. If it doesn't for your particular setup we'd like to hear.
$ npm install nanocomponent
FAQs
Native DOM components that pair nicely with DOM diffing algorithms
We found that nanocomponent demonstrated a not healthy version release cadence and project activity because the last version was released a year ago. It has 30 open source maintainers collaborating on the project.
Did you know?
Socket for GitHub automatically highlights issues in each pull request and monitors the health of all your open source dependencies. Discover the contents of your packages and block harmful activity before you install or update your dependencies.
Research
Security News
Socket researchers uncover a malicious npm package posing as a tool for detecting vulnerabilities in Etherium smart contracts.
Security News
Research
A supply chain attack on Rspack's npm packages injected cryptomining malware, potentially impacting thousands of developers.
Research
Security News
Socket researchers discovered a malware campaign on npm delivering the Skuld infostealer via typosquatted packages, exposing sensitive data.